#include <iostream>
#include <memory>
#include <algorithm>

using std::cout;
using std::endl;
using std::copy;

template<typename T>
class Vector
{
public:
    /* typedef T * iterator;//C++98写法 */
    using iterator = T *;//C++11的写法

    iterator begin()
    {
        return _start;
    }

    iterator end()
    {
        return _finish;
    }

    Vector()
    : _start(nullptr)
    , _finish(nullptr)
    , _end_of_storage(nullptr)
    {

    }
    ~Vector();
    
    void push_back(const T &); 
    void pop_back();    
    
    int size() const;
    int capacity() const;
private:
    void reallocate();//重新分配内存,动态扩容要用的
private:    
    static std::allocator<T> _alloc;
    
    T * _start;      //指向数组中的第一个元素
    T * _finish; //指向最后一个实际元素之后的那个元素
    T * _end_of_storage;        //指向数组本身之后的位置
};

template<typename T>
std::allocator<T> Vector<T>::_alloc;//静态数据成员的初始化

template<typename T>
Vector<T>::~Vector()
{
    if(_start)
    {
        while(_start != _finish)
        {
            _alloc.destroy(--_finish);//销毁对象
        }
        _alloc.deallocate(_start, capacity());//回收空间
    }
}

template<typename T>
void Vector<T>::push_back(const T &value)
{
    //容量够不够
    if(size() == capacity())
    {
        //扩容
        reallocate();
    }

    if(size() < capacity())
    {
        //构建对象
        _alloc.construct(_finish++, value);
    }
}

template<typename T>
void Vector<T>::pop_back()
{
    if(size() > 0)
    {
        _alloc.destroy(--_finish);//销毁对象
    }

}
    
template<typename T>
int Vector<T>::size() const
{
    return _finish - _start;
}

template<typename T>
int Vector<T>::capacity() const
{
    return _end_of_storage - _start;
}

template<typename T>
void Vector<T>::reallocate()
{
    //扩容
    //1、需要申请空间，空间应该是老的空间的两倍
    int oldCapacity = capacity();
    int newCapacity =  2 * oldCapacity > 0 ? 2 * oldCapacity : 1;
    T *ptmp  = _alloc.allocate(newCapacity);
    
    //2、然后将老的空间上的元素拷贝到新到空间来
    if(_start)
    {
        /* copy(_start, _finish, ptmp); */
        std::uninitialized_copy(_start, _finish, ptmp);
        //3、再将老的空间的元素销毁以及空间进行回收
        while(_start != _finish)
        {
            //将老的空间上的元素销毁了
            _alloc.destroy(--_finish);
        }
        _alloc.deallocate(_start, oldCapacity);//回收老的空间
        
    }
    //4、将三个指针与新的空间之间产生联系
    _start = ptmp;
    _finish = ptmp + oldCapacity;
    _end_of_storage = ptmp + newCapacity;
}

template <typename Container>
void printCapacity(const Container &con)
{
    cout << "con.size() = " << con.size() << endl;
    cout << "con.capacity() = " << con.capacity() << endl;
}

void test()
{
    Vector<int> number;
    printCapacity(number);

    cout << endl;
    number.push_back(1);
    printCapacity(number);

    cout << endl;
    number.push_back(2);
    printCapacity(number);

    cout << endl;
    number.push_back(3);
    printCapacity(number);

    cout << endl;
    number.push_back(4);
    printCapacity(number);

    cout << endl;
    number.push_back(5);
    printCapacity(number);

    cout << endl;
    number.push_back(6);
    printCapacity(number);

    cout << endl;
    number.push_back(7);
    printCapacity(number);

    cout << endl;
    number.push_back(5);
    printCapacity(number);

    cout << endl;
    number.push_back(6);
    printCapacity(number);

    cout << endl;
    number.push_back(7);
    printCapacity(number);

    for(auto &elem : number)
    {
        cout << elem << "  ";
    }
    cout << endl;
}

int main(int argc, char **argv)
{
    test();
    return 0;
}

